# -*- coding: utf-8 -*-

"""
难度预测器
"""

import random
import numpy as np
import sqlite3
import os


class DifficultyPredictor:
    def __init__(self, model_path=None):
        """初始化难度预测器"""
        self.model = None
        self.model_path = model_path
        if model_path and os.path.exists(model_path):
            self.load_model()
        
    def load_model(self):
        """加载TensorFlow Lite模型"""
        try:
            import tensorflow as tf
            self.interpreter = tf.lite.Interpreter(model_path=self.model_path)
            self.interpreter.allocate_tensors()
            self.input_details = self.interpreter.get_input_details()
            self.output_details = self.interpreter.get_output_details()
            print("TensorFlow Lite模型加载成功")
        except ImportError:
            print("TensorFlow未安装，使用规则基础预测")
            self.interpreter = None
        except Exception as e:
            print(f"模型加载失败: {e}")
            self.interpreter = None

    def predict_difficulty(self, player_data, emotion_data):
        """
        根据玩家数据和情感数据预测适合的难度
        
        Args:
            player_data (dict): 玩家历史数据
            emotion_data (dict): 情感分析数据
            
        Returns:
            str: 推荐难度级别
        """
        # 如果有训练好的模型且能正常加载，则使用模型预测
        if self.interpreter is not None:
            try:
                return self._predict_with_model(player_data, emotion_data)
            except Exception as e:
                print(f"模型预测出错: {e}")
        
        # 否则使用原有的规则基础预测
        return self._predict_with_rules(player_data, emotion_data)
        
    def _predict_with_model(self, player_data, emotion_data):
        """
        使用训练好的模型进行预测
        
        Args:
            player_data (dict): 玩家历史数据
            emotion_data (dict): 情感分析数据
            
        Returns:
            str: 推荐难度级别
        """
        # 准备输入数据
        # 假设模型需要7天的历史数据，每天包含完成时间、错误次数、暂停次数
        history_data = self._prepare_history_data(player_data)
        
        # 设置模型输入
        self.interpreter.set_tensor(self.input_details[0]['index'], history_data.astype(np.float32))
        
        # 运行推理
        self.interpreter.invoke()
        
        # 获取输出
        output_data = self.interpreter.get_tensor(self.output_details[0]['index'])
        predicted_class = np.argmax(output_data[0])
        
        # 将类别映射到难度标签
        difficulty_levels = {0: "简单", 1: "中等", 2: "困难", 3: "专家"}
        return difficulty_levels.get(predicted_class, "中等")
        
    def _prepare_history_data(self, player_data):
        """
        准备历史数据用于模型输入
        
        Args:
            player_data (dict): 玠家历史数据
            
        Returns:
            np.array: 格式化后的数据 (1, 7, 3)
        """
        # 这里简化处理，实际应该从数据库获取7天的历史数据
        # 假设数据格式为 [完成时间(秒), 错误次数, 暂停次数]
        history = np.random.rand(7, 3)  # 示例数据
        
        # 根据player_data调整示例数据
        if "avg_time" in player_data:
            history[:, 0] = player_data["avg_time"] / 3600.0  # 归一化到小时
            
        return np.expand_dims(history, axis=0)  # 添加batch维度

    def _predict_with_rules(self, player_data, emotion_data):
        """
        基于规则的难度预测（原有实现）
        
        Args:
            player_data (dict): 玩家历史数据
            emotion_data (dict): 情感分析数据
            
        Returns:
            str: 推荐难度级别
        """
        # 简化实现，实际应该基于机器学习模型
        
        # 考虑玩家历史表现
        avg_time = player_data.get("avg_time", 300)  # 默认5分钟
        success_rate = player_data.get("success_rate", 0.7)  # 默认70%成功率
        
        # 考虑情绪状态
        emotion = emotion_data.get("dominant_emotion", "平静")
        confidence = emotion_data.get("confidence", 0.8)
        
        # 简单的规则基础预测
        if avg_time < 120 and success_rate > 0.8:  # 快速且成功率高
            base_difficulty = 3  # 困难
        elif avg_time > 600 or success_rate < 0.5:  # 慢或成功率低
            base_difficulty = 1  # 简单
        else:
            base_difficulty = 2  # 中等
            
        # 根据情绪调整
        if emotion in ["兴奋", "快乐"] and confidence > 0.8:
            base_difficulty += 1
        elif emotion in ["悲伤", "忧郁"] and confidence > 0.7:
            base_difficulty -= 1
            
        # 确保难度在有效范围内
        base_difficulty = max(1, min(4, base_difficulty))
        
        difficulty_levels = {1: "简单", 2: "中等", 3: "困难", 4: "专家"}
        return difficulty_levels[base_difficulty]
        
    def adjust_difficulty_during_game(self, game_progress, time_spent, moves_count):
        """
        在游戏过程中动态调整难度
        
        Args:
            game_progress (float): 游戏完成度 (0-1)
            time_spent (int): 已用时间(秒)
            moves_count (int): 已移动步数
            
        Returns:
            str: 调整建议
        """
        # 简化实现
        if game_progress < 0.3 and time_spent > 180:  # 前30%进度用时超过3分钟
            return "提供提示"
        elif game_progress > 0.7 and moves_count < 50:  # 后30%进度步数很少
            return "增加挑战"
        else:
            return "保持当前难度"
            
    def adjust_puzzle_parameters(self, difficulty_level):
        """
        根据预测的难度等级调整拼图参数
        
        Args:
            difficulty_level (str): 难度等级
            
        Returns:
            dict: 调整后的拼图参数
        """
        # 根据难度调整拼图参数
        params = {
            "简单": {
                "grid_size": 3,      # 3x3网格
                "rotation_range": 0, # 无旋转
                "show_guidelines": True,  # 显示辅助线
                "time_limit": None   # 无时间限制
            },
            "中等": {
                "grid_size": 4,      # 4x4网格
                "rotation_range": 0, # 无旋转
                "show_guidelines": False, # 不显示辅助线
                "time_limit": None   # 无时间限制
            },
            "困难": {
                "grid_size": 5,      # 5x5网格
                "rotation_range": 90, # 90度旋转
                "show_guidelines": False, # 不显示辅助线
                "time_limit": None   # 无时间限制
            },
            "专家": {
                "grid_size": 6,      # 6x6网格
                "rotation_range": 180, # 180度旋转
                "show_guidelines": False, # 不显示辅助线
                "time_limit": 600    # 10分钟时间限制
            }
        }
        
        return params.get(difficulty_level, params["中等"])